#ifndef _FILTER_CONTROL_
#define _FILTER_CONTROL_

#include "Globals.H"
#include "GUI.h"
#include "Misc.h"
///#define __MULTI_INSTANCE__
///#define __MULTIDISPLAY__

//#define  __EDIT_CHROMAKEY_VALUE__
#ifdef __EDIT_CHROMAKEY_VALUE__
#include "TCCChromakeyControl.h"
#endif
//#define __TCC_AUDIO_OUTPUT_CONTROL_FILTER__
#ifdef __TCC_AUDIO_OUTPUT_CONTROL_FILTER__
static const GUID CLSID_TCCAudioOutputControlFilter={0x68511c1, 0xaeec, 0x4683, {0x8d, 0x84, 0x32, 0x7c, 0x7d, 0x9f, 0xaa, 0x44}};
#endif

#define __FILTER_SPEED_CONTROL__
#include <streams.h>
#include <strmif.h>

#if !defined (SAFE_RELEASE)
#define SAFE_RELEASE(x)	if(x){x->Release(); x=NULL;}
#endif

#if !defined (SAFE_REMOVE_FILTER)
#define SAFE_REMOVE_FILTER(x, y)  if (x && y) { y->RemoveFilter(x); SAFE_RELEASE(x); }
#endif

#ifdef TCCAUDIO_SELECT	
#include "TCCAudioSelect.h"
#endif

// replace mediaInfo[11/27/2009 b090136]
#include "TCCAVInfo.h"

#include "TCCInterface.h"

// decide print decoding information setting [12/16/2009 b090136]
#include "TCCPrintInfo.h"
#include "VPU_DEC_Interface.h"

/*****************  TCCVrend Interface ********************/
typedef BOOL (CALLBACK *TCCINFORMATIONRECEIVECALLBACK)(DWORD, PVOID, PVOID);

static const GUID CLSID_TCCVREND =
{ 0xcd0fb4f0, 0x69f3, 0x4fa5, { 0xb4, 0x2a, 0x8, 0xdc, 0x41, 0x51, 0x6b, 0x3a } };

static const GUID IID_ITccVren3={0xf9a3efd9, 0x6812, 0x4166, {0x86, 0x79, 0x72, 0x80, 0x82, 0xce, 0x3f, 0xb6}};

// {E93D78F9-D4ED-4bed-B262-6CFE261D61E6}
static const GUID IID_ITCCVideoSampleGrabber={0xe93d78f9, 0xd4ed, 0x4bed, {0xb2, 0x62, 0x6c, 0xfe, 0x26, 0x1d, 0x61, 0xe6}};

struct ITCCVideoSampleGrabber: public IUnknown
{
	virtual HRESULT GetSample(const BYTE *pBuffer, int *pWidth, int *pHeight, int *pBufferSize, DWORD dwMilliseconds, int *pInterleavedMode, BOOL *pbInterleaved, int *pReserved)=0;
    virtual HRESULT SetPreview(const BYTE *pBuffer, const int imgWidth, const int imgHeight, TCCINFORMATIONRECEIVECALLBACK pfn, PVOID pParam)=0;
};

struct VrenderModeFlag{
	unsigned int mode; 
	// 0: default(no alpha blending & no croma key)
	// 1: chroma key(using xCHValue)
	// 2: alpha blending 25%
	unsigned int left;
	unsigned int top;
	unsigned int width;
	unsigned int height;
//	unsigned int Chromakey;
#ifdef __ROTATE_INCLUDE__
	unsigned int Rotate;
#endif
	unsigned int reserved[5];
};

typedef struct tagAlg01Info {
	double StrDefault;
	double StrYishG;
	double StrYG;
	double StrGishY;
	double StrY;
	double StrYishO;
	double StrO;
	double StrOPin;
	double StrPin;
	double StrPishPin;
	double StrRishO;
	double StrR;
	double StrPishR;
	double StrRP;
	double StrRishP;
	double StrP;
	double StrBishP;
	double StrPishB;
	double StrB;
	double StrGishB;
	double StrBG;
	double StrBishG;
	double StrG;
} Alg01Info;
typedef struct tagAlg23Info {
	int StrDefault;
	int StrYishG;
	int StrYG;
	int StrGishY;
	int StrY;
	int StrYishO;
	int StrO;
	int StrOPin;
	int StrPin;
	int StrPishPin;
	int StrRishO;
	int StrR;
	int StrPishR;
	int StrRP;
	int StrRishP;
	int StrP;
	int StrBishP;
	int StrPishB;
	int StrB;
	int StrGishB;
	int StrBG;
	int StrBishG;
	int StrG;
} Alg23Info;
struct VIQEModeFlag
{
	int m_nDIOnOff;
	int m_nDISPOnOff;
	int m_nHPFOnOff;
	int m_nDNSPOnOff;
	int m_nDNTSOnOff;
	int m_nHISOnOff;
	int m_nGAMUTOnOff;
	int m_nHalfOnOff;

	int m_nHPFChroma;
	int m_nHPFLuma;

	int m_nDNSP;

	int m_nDNTSTmpChroma;
	int m_nDNTSTmpLuma;
	int m_nDNTSSpaChroma;
	int m_nDNTSSpaLuma;

	int m_nGamutAlgorithm;
	Alg01Info Alg01;	
	Alg23Info Alg23Hue;
	Alg23Info Alg23Sat;
	Alg23Info Alg23Con;
	Alg23Info Alg23Bri;
	int m_nHisto[16];
};

//adf85a65-358f-4fcd-86b1-b8f3d6540324
static const GUID IID_ITccVren = 
{ 0xadf85a65, 0x358f, 0x4fcd, {0x86, 0xb1, 0xb8, 0xf3, 0xd6, 0x54, 0x03, 0x24} };

DECLARE_INTERFACE_(ITccVren, IUnknown)
{
	STDMETHOD(GetModeFlag)(THIS_ VrenderModeFlag* Flag) PURE;
	STDMETHOD(SetModeFlag)(THIS_ VrenderModeFlag Flag) PURE;
	STDMETHOD(SetAVSync)(THIS_ BOOL bAVSync) PURE;	
	STDMETHOD(SetM2MScaler)(THIS_ BOOL bM2MScaler) PURE;
	STDMETHOD(SetAlphaBlanding)(THIS_ BOOL AlphaBlanding) PURE;
};
typedef BOOL (CALLBACK *TCCINFORMATIONRECEIVECALLBACK)(DWORD, PVOID, PVOID);
DECLARE_INTERFACE_(ITccVren2, ITccVren)
{
	// blt YUV420 on video LCD layer
	STDMETHOD(BitBltYuv420)(THIS_ BYTE* pBuf, CONST INT imgWidth, CONST INT imgHeight) PURE;
	STDMETHOD(SetPreviewYuv420)(THIS_ CONST BYTE *pBuffer, CONST int imgWidth, CONST int imgHeight, TCCINFORMATIONRECEIVECALLBACK pfn, PVOID pParam) PURE;
};


DECLARE_INTERFACE_(ITccVren3, ITccVren2)
{
	STDMETHOD(CaptureSampleBufferYuv420)(THIS_ CONST BYTE *pBuffer, int *pWidth, int *pHeight, int *pBufferSize, DWORD dwMilliseconds) PURE;
};

// {829F215E-007C-4398-84AC-EEFF7DD55145}
static const GUID IID_ITccVren4 = 
{ 0x829f215e, 0x7c, 0x4398, { 0x84, 0xac, 0xee, 0xff, 0x7d, 0xd5, 0x51, 0x45 } };

DECLARE_INTERFACE_(ITccVren4, ITccVren3)
{
	STDMETHOD(SetLCDDisable)(THIS_ BOOL bLCDDisable) PURE;
};

// {29B2010A-42F1-4a40-84D5-5F995AC324FE}
static const GUID IID_ITccVren5 = 
{ 0x29b2010a, 0x42f1, 0x4a40, { 0x84, 0xd5, 0x5f, 0x99, 0x5a, 0xc3, 0x24, 0xfe } };

DECLARE_INTERFACE_(ITccVren5, ITccVren4)
{
	STDMETHOD(ResizeCurrentFrame)(THIS_	VrenderModeFlag flag) PURE;
	STDMETHOD(GetVIQEModeFlag)(THIS_ VIQEModeFlag* Flag) PURE;
	STDMETHOD(SetVIQEModeFlag)(THIS_  VIQEModeFlag Flag) PURE;	
};

// {C9941A80-D17E-4638-879A-C78E9577AD9E}
static const GUID IID_ITccVren6 = 
{ 0xc9941a80, 0xd17e, 0x4638, { 0x87, 0x9a, 0xc7, 0x8e, 0x95, 0x77, 0xad, 0x9e } };

DECLARE_INTERFACE_(ITccVren6, ITccVren5)
{
	STDMETHOD(GettVRender)(THIS_ tVRender *pVflag, DWORD dwMilliseconds) PURE;		
};

/*****************  TCCCaptionRendInterface ********************/
// {09311F36-02FB-460c-BE32-BC4BD4AF9E8C}
static const GUID IID_ITCCBitmapRenderer={0x9311f36, 0x2fb, 0x460c, {0xbe, 0x32, 0xbc, 0x4b, 0xd4, 0xaf, 0x9e, 0x8c}};

struct ITCCBitmapRenderer: public IUnknown
{
	virtual HRESULT GetWindow(HWND *phWnd)=0;
	virtual HRESULT SetWindow(HWND hWnd)=0;

	virtual HRESULT GetDestinationRect(RECT *prt)=0;
	virtual HRESULT SetDestinationRect(RECT *prt)=0;

	virtual HRESULT GetBackgroundColor(COLORREF *pcr)=0;
	virtual HRESULT SetBackgroundColor(COLORREF cr)=0;
};


// {CFE5E520-6D4C-433b-B5CA-EC0C77F1C168}
static const GUID IID_ITCCSubtitleRenderer={0xcfe5e520, 0x6d4c, 0x433b, { 0xb5, 0xca, 0xec, 0xc, 0x77, 0xf1, 0xc1, 0x68}};

struct ITCCSubtitleRenderer: public ITCCBitmapRenderer
{
    enum STYLE
    {
        STYLE_ALIGN_VERTICAL_TOP=0,
        STYLE_ALIGN_VERTICAL_CENTER=1,
        STYLE_ALIGN_VERTICAL_BOTTOM=2,
        
        STYLE_ALIGN_HORIZONTAL_LEFT=0,
        STYLE_ALIGN_HORIZONTAL_CENTER=4,
        STYLE_ALIGN_HORIZONTAL_RIGHT=8,
        
        
        STYLE_ALIGN_LEFTTOP=0,
        STYLE_ALIGN_LEFTCENTER=1,
        STYLE_ALIGN_LEFTBOTTOM=2,
        
        STYLE_ALIGN_CENTERTOP=4,
        STYLE_ALIGN_CENTER=5,
        STYLE_ALIGN_CENTERBOTTOM=6,
        
        STYLE_ALIGN_RIGHTTOP=8,
        STYLE_ALIGN_RIGHTCENTER=9,
        STYLE_ALIGN_RIGHTBOTTOM=10,
        
        STYLE_STROKE=1<<4,
    };

    virtual HRESULT GetEnable(BOOL *pb)=0;
    virtual HRESULT SetEnable(BOOL b)=0;

    virtual HRESULT GetFont(LOGFONT *plf)=0;
    virtual HRESULT SetFont(LOGFONT *plf)=0;

    virtual HRESULT GetStyle(unsigned int *pStyle)=0;
    virtual HRESULT SetStyle(unsigned int Style)=0;

    virtual HRESULT GetLeftMargin(int *pPercentage)=0;
    virtual HRESULT SetLeftMargin(int Percentage)=0;

    virtual HRESULT GetTopMargin(int *pPercentage)=0;
    virtual HRESULT SetTopMargin(int Percentage)=0;

    virtual HRESULT GetRightMargin(int *pPercentage)=0;
    virtual HRESULT SetRightMargin(int Percentage)=0;

    virtual HRESULT GetBottomMargin(int *pPercentage)=0;
    virtual HRESULT SetBottomMargin(int Percentage)=0;
};


// {5F9B1AA8-E7CC-4c24-B05A-5D56AFB68F48}
static const GUID IID_ITCCSubtitleRenderer2={0x5f9b1aa8, 0xe7cc, 0x4c24, {0xb0, 0x5a, 0x5d, 0x56, 0xaf, 0xb6, 0x8f, 0x48}};

struct ITCCSubtitleRenderer2: public ITCCSubtitleRenderer
{
public:
    virtual HRESULT ReRender(void)=0;
};


struct CaptionRenderInfo{
	unsigned char enable;	
	unsigned int left;
	unsigned int top;
	unsigned int width;
	unsigned int height;
	DWORD fontsize;
	DWORD fontcolor;
};


static const GUID IID_IExportBitBlt={0x98be5363, 0x1ad7, 0x4e36, {0xab, 0x1e, 0x41, 0x71, 0xb1, 0x8a, 0xbd, 0x45}};

struct IExportBitBlt: public IUnknown
{
public:
    virtual HRESULT BitBltToFrameBuffer(int x, int y, int w, int h, void *pSource, int SourceWidthBytes, int sx, int sy)=0;
};

/***********  TCCCDKDemuxnterface for InnerSubtitle **************/

// {6A95946E-2B74-40db-99A8-BBB60D03B867}
static const GUID IID_ITCCInnerSubtitleSelect = 
{ 0x6a95946e, 0x2b74, 0x40db, { 0x99, 0xa8, 0xbb, 0xb6, 0xd, 0x3, 0xb8, 0x67 } };

DECLARE_INTERFACE_(ITCCInnerSubtitleSelect, IUnknown)
{
	STDMETHOD(GetSubtitleSubStreamNumber)(unsigned int *num) PURE;
	STDMETHOD(GetSubtitleCurrentSubStream)(unsigned int* id) PURE;
	STDMETHOD(SetSubtitleSubStream)(unsigned int id) PURE;
};

/*****************  TCCCaptionParserInterface ********************/
/* DivX Caption Type */
typedef enum
{
	E_DIVX_CAPTION_SAMI,		// Microsoft SAMI(Synchronized Accessible Media Interchange)
	E_DIVX_CAPTION_SUBRIP,		// SubRip
	E_DIVX_CAPTION_SUBVIEWER,	// SubViewer 1.0 & 2.0
	E_DIVX_CAPTION_SSA,		// Sub Station Alpha v4.00 Script Format

	E_DIVX_CAPTION_MAX
} E_DIVX_CAPTION_TYPE;

// {6A95946D-2B73-40da-99A8-BBB60D03B867}
static const GUID IID_ITccCaptionParser = 
{ 0x6a95946d, 0x2b73, 0x40da, { 0x99, 0xa8, 0xbb, 0xb6, 0xd, 0x3, 0xb8, 0x67 } };

DECLARE_INTERFACE_(ITccCaptionParser, IUnknown)
{
	STDMETHOD(GetType)(THIS_ DWORD* CaptionType) PURE;
	STDMETHOD(SetType)(THIS_ DWORD CaptionType) PURE;
	STDMETHOD(SetDuration)(THIS_ double Duration) PURE;
	STDMETHOD(SetStartTime)(THIS_ LONGLONG StartTime) PURE;
	STDMETHOD(SetLanguage)(THIS_ int LanguageIndex) PURE;
	STDMETHOD(SetCodePage)(THIS_ UINT CodePage) PURE;
};


static const GUID IID_IVideoDestination3={0x9d0e796b, 0x1159, 0x4d1d, { 0x83, 0xc6, 0x9d, 0x32, 0x8d, 0xab, 0xac, 0x74}}; // {9D0E796B-1159-4d1d-83C6-9D328DABAC74}

struct IVideoDestination3: public IUnknown
{
    // IVideoDestination
    virtual HRESULT SetLCDImage(int n)=0;

    // IVideoDestination2
    virtual HRESULT GetLCDImage(int *pn)=0;

    virtual HRESULT SetLCDController(int LCDC, int Image)=0;
    virtual HRESULT GetLCDController(int *pLCDC, int *pImage)=0;

    // IVideoDestination3
    virtual HRESULT SetEnable(BOOL b)=0;
    virtual HRESULT GetEnable(void)=0;
};


static const GUID CLSID_TCVideoDuplicator={0x55233cd, 0xc362, 0x41b1, {0xbf, 0xcb, 0xb7, 0xc7, 0x37, 0xa4, 0x38, 0x4}}; // {055233CD-C362-41b1-BFCB-B7C737A43804}

static const GUID IID_ITCVideoDuplicator={0x2779560b, 0xccea, 0x4520, {0x8e, 0x60, 0xd8, 0x86, 0x5e, 0x4a, 0x0, 0x29}}; // {2779560B-CCEA-4520-8E60-D8865E4A0029}

struct ITCVideoDuplicator: public IUnknown
{
    virtual HRESULT SetOutputPinCount(int c)=0;
    virtual HRESULT GetOutputPinCount(int *pc)=0;

    virtual HRESULT QueryConnectedDownstreamFilter(int n, IBaseFilter **ppFilter)=0;
};


class CFilterControl {

public:
	CFilterControl(void);
	~CFilterControl(void);
	int CreateFilterGraph(void);
	void DestroyFilterGraph(void);
	void DeleteFiltersForPlaying(void);
	BOOL GetPlayDuration(double *duration);
	BOOL GetCurrentPlayTime(double *Pos);
	int CreateFilterForPlaying(TCHAR *FileName,CRect OutputSize, HWND hWnd, CaptionRenderInfo CaptionInfo);
	BOOL SetCurrentPlayTime(double pos);
	HRESULT RunGraph();
	BOOL StopGraph();
	BOOL PauseGraph();
	BOOL SetAudioVolume(unsigned int AudioVolume);
	BOOL GetAudioVolume(unsigned int* pAudioVolume);
	unsigned int GetSeekablility();
	BOOL SetNewSeekTime(LONGLONG llPTS);

#ifdef VPU_CLOCK_CONTROL
	BOOL SetVPUClockControl(int VBUS, int VCODEC);
#endif

	int SetVIQEmodes(VIQEModeFlag	flag);
	int GetVIQEmodes(VIQEModeFlag	&flag);

#ifdef __RESIZE__
	void	CurrentFrameResize(CRect vrect);
#endif
#ifdef __FILTER_SPEED_CONTROL__
	// Filter Speed Control;	
	int m_nIndex;
	double	dSpeedSet(int nIndex, int nType);
	void FilterSpeedDown(int nType);
	void FilterSpeedUp(int nType);
	void FilterSpeedNormal();
	double GetCurrentSpeed(int nType);
	IMediaControl *m_pMC;	// IMediaControl interface
	IMediaSeeking *m_pMediaSeeking;
#endif
	
	int SetVRendSize(CRect NewOutputSize);	
	BOOL	GettVRender(tVRender &pVflag, DWORD dwMilliseconds);	
	
	int SetCaptionLanguage(int index);
	int SetCaptionHWND(HWND hWnd);
	int SetCaptionInfo(CaptionRenderInfo CaptionInfo);
    void ReRenderSubtitle(void);
    BOOL BitBltToHDMI(int x, int y, int w, int h, void *pSource, int SourceWidthBytes, int sx, int sy);
	BOOL CaptureCurrentSampleBufferYuv420(BYTE *pBuffer, int *pWidth, int *pHeight, int *pBufferSize, DWORD dwMilliseconds,BOOL *bInterleaved);
#ifdef __EC_COMPLETE_INCLUDE__
	IMediaEventEx *m_pMex;
	HRESULT GetNotifyEvent(long *evCode,LONG *param1,LONG *param2);
	HRESULT FreeEventParams(long evCode,LONG param1,LONG param2);
#endif

    HRESULT SetLCDController(int Renderer, int LCDC, int Image);

#ifdef __ROTATE_INCLUDE__
	int RotateVRend(CRect NewOutputSize, int Mode);
#endif
public:
	VrenderModeFlag Rendererflag;


public:
	IBaseFilter* mpCDKDemux_forInnerSub;
	UINT m_InnerSubTrackNum;
	UINT m_InnerSubStreamId;
	BOOL SelectInnerSubNum();
	BOOL m_CheckDisplayIntCaption;
	BOOL m_CheckDisplayExtCaption;

protected:
	BOOL mIsRunning;

	IGraphBuilder *mpGraph;
	IBaseFilter* mpVideoRenderer;
	IBaseFilter* mpAsyncReader;
	IBaseFilter* mpCaptionParser;
	IBaseFilter* mpCaptionRenderer;

#ifdef __TCC_AUDIO_OUTPUT_CONTROL_FILTER__
	IBaseFilter* m_pTCCAudioOutputControlFilter;
#endif

    int mLCDImage;
public:
#ifdef __MULTIDISPLAY__
    IBaseFilter *mpDuplicator;
#endif

    int mPrimaryRendererLCDC;
    int mPrimaryRendererImage;

    bool mbSeconldyRenderer;
    int mSecondlyRendererLCDC;
    int mSecondlyRendererImage;

protected:
	
#ifdef VPU_CLOCK_CONTROL
	IBaseFilter* mVpuDec;
#endif

	BOOL CheckCoCreateInstance(HRESULT &hr, REFCLSID rclsid, REFIID riid, LPVOID* ppv, LPCTSTR pszErrorMessage);
	BOOL AddFilterForRecording(void);
	BOOL AddFilterForCapture(void);
	BOOL RemoveFilter(void);
	BOOL Disconnect(IBaseFilter *pBaseFilter, LPCTSTR pszPinName, PIN_DIRECTION Dir);
	BOOL CheckAddFilter(HRESULT &hr, IBaseFilter *pBaseFilter, LPCTSTR pszFilterName);
	BOOL CheckConnect(HRESULT &hr, IBaseFilter *pBaseFilterUpstream, LPCTSTR pszOutpinName, IBaseFilter *pBaseFilterDownstream, LPCTSTR pszInpinName, LPCTSTR pszErrorMessage);
//	static HRESULT FindPin(IBaseFilter *pFilter, PIN_DIRECTION Dir, LPCTSTR pszPinName, IPin **ppPin);

#ifdef TCCAUDIO_SELECT
public:
	IBaseFilter *m_pAVIDemuxer;
	UINT m_AudioTrackNum;
	UINT m_AudioStreamId;
	BOOL SelectAudioNum();
#endif

	// MediaInfo Replace [11/27/2009 b090136]
	int Get_VideoHeight();
	int Get_VideoWidth();
	double Get_Bitrate();
	int Get_SourceHeight();
	int Get_SourceWidth();	
	
	int Get_AudioCodec();
	int Get_AudioChannel();
	int Get_AudioBitrate();
	int Get_AudioSamplerate();

	VideoInfo Get_VideoInfo();
	AudioInfo Get_AudioInfo();

	BOOL isNullVideoDec();
	BOOL isAudioRender();


	void SetPrintInformation(BOOL bPrint);

#ifdef __EDIT_CHROMAKEY_VALUE__
	void SetRendererChromakeyValue(int nRValue, int nGValue, int BValue);
#endif
	stVRM	m_stVRM[14];		// Video Route Manager Array
	int		m_nType;
	bool	m_bSetRegistry;

	void	SetDefaultPreset();	
	CRect	GetPresetRect(int nOrder);	// 0 : return Primary Rect, 1 : return Secondary Rect
	stVRM	GetPreset(int nOrder);

	void GetGMCOption(bool *Status);
	void GetWeightedPrediction(bool *Status);
	void GetAspectRatio(int *AspectRatio);
};

#endif